Uploading a list of grouped verbs
To find synonims for English words we can use the WordNet and its R wrapper in the wordnet package. (https://bernhardlearns.blogspot.com/2017/04/cleaning-words-with-r-stemming.html)
verbs %<>% str_trim(verb)
Error in match.arg(side) : object 'verb' not found
#verbs_qp <- verbs %>% filter(character=="QN") %>% select(verb)
up2 <- up %>% subset(upos %in% c("VERB"))
up2 %<>% subset(lemma %in% as.vector(verbs$verb))
up2 %<>% merge(txt_freq(up2$lemma), by.x= "lemma", by.y = "key")
# up2 %<>% count(lemma) %>% mutate(freq = n / sum(n)) %>% arrange(desc(n))
up2 %<>% left_join(verbs, by=c("lemma"="verb"))
up2 %<>% unique()
up2 %<>% separate(doc_id, c("doc", "gcode"), sep = ", ")
# verbs %<>% merge(up2, by.x = "verb", by.y="lemma")
up2 %>%
distinct(lemma, .keep_all = T) %>%
group_by(character) %>% arrange(desc(freq)) %>% slice(1:12) %>% ungroup() %>%
mutate(verb = reorder_within(lemma, by = freq, within = character)) %>%
ggplot(aes(x = verb, y = freq, fill = character)) +
geom_col(show.legend = FALSE) +
labs(x = "Verbs", y = "frequency") +
facet_wrap(~character, ncol = 3, scales = "free_y") +
coord_flip() +
scale_x_reordered() +
theme(axis.text.y = element_text(size = 6))

up2 %>%
distinct(lemma, .keep_all = T) %>%
group_by(character) %>% summarize(sum=sum(freq)) %>% #arrange(desc(sum)) %>%
ggplot(aes(x = character, y = sum)) +
geom_bar(stat = "sum",show.legend = FALSE)

up2 %>%
group_by(gcode,character) %>% count(lemma) %>% summarize(sum=sum(n), .groups = "keep") %>%
mutate(character = reorder_within(character, by = sum, within = gcode)) %>%
ggplot(aes(x = character, y = sum, fill = gcode)) +
geom_col(show.legend = FALSE) +
labs(x = "Verbs", y = "frequency") +
facet_wrap(~gcode, ncol = 4, scales = "free_y") +
coord_flip() +
scale_x_reordered() +
theme(axis.text.y = element_text(size = 6))

verb_phrase_simp <- "((A|N)*N(P+D*(A|N)*N)*P*(M|V)*V(M|V)*|(M|V)*V(M|V)*D*(A|N)*N(P+D*(A|N)*N)*|(M|V)*V(M|V)*(P+D*(A|N)*N)+|(A|N)*N(P+D*(A|N)*N)*P*((M|V)*V(M|V)*D*(A|N)*N(P+D*(A|N)*N)*|(M|V)*V(M|V)*(P+D*(A|N)*N)+))" # Simple verb Phrase
verb_phrase_with_cc <- "(((A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*(C(D(CD)*)*(A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*)*)(P(CP)*)*(M(CM)*|V)*V(M(CM)*|V)*(C(M(CM)*|V)*V(M(CM)*|V)*)*|(M(CM)*|V)*V(M(CM)*|V)*(C(M(CM)*|V)*V(M(CM)*|V)*)*(D(CD)*)*((A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*(C(D(CD)*)*(A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*)*)|(M(CM)*|V)*V(M(CM)*|V)*(C(M(CM)*|V)*V(M(CM)*|V)*)*((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)+|((A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*(C(D(CD)*)*(A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*)*)(P(CP)*)*((M(CM)*|V)*V(M(CM)*|V)*(C(M(CM)*|V)*V(M(CM)*|V)*)*(D(CD)*)*((A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*(C(D(CD)*)*(A(CA)*|N)*N((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)*)*)|(M(CM)*|V)*V(M(CM)*|V)*(C(M(CM)*|V)*V(M(CM)*|V)*)*((P(CP)*)+(D(CD)*)*(A(CA)*|N)*N)+))" # Verb phrase with coordination conjunction
up3 <- up %>% subset(sentence %in% up2$sentence)
up3 %<>% separate(doc_id, c("doc", "gcode"), sep = ", ")
up3 %<>% mutate(phrase_tag=as_phrasemachine(upos,type="upos"))
verb_phrases <- keywords_phrases(up3$phrase_tag, term = up3$token,
pattern = verb_phrase_simp, is_regex = TRUE,
ngram_max = 7,
detailed = TRUE)
head(sort(table(verb_phrases$keyword), decreasing=TRUE), 20)
employees are we have WE GET WE GET THINGS which is WE GET THINGS DONE
71 52 48 48 48 46
that are We have Engaging Local Communities Manage Our Manage Our People We encourage
35 33 29 29 29 29
We Manage We Manage Our We Manage Our People It is who are enables us
29 29 29 26 26 24
which are We do
24 23
library(textstem)
verb_phrases2 <-verb_phrases
lemmed <- verb_phrases %>% unnest_tokens(word,keyword,token = "ngrams", n=1)
lemmed %<>% mutate(lemma=lemmatize_words(word, dictionary = lexicon::hash_lemmas))
lemmed_ss <- lemmed %>% subset(lemma %in% verbs$verb[verbs$character=="QP"])
verb_phrases2 %<>% subset(start %in% lemmed_ss$start & end %in% lemmed_ss$end)
verb_phrases2 %>%
filter(ngram>=3) %>%
merge(txt_freq(verb_phrases2$keyword), by.x= "keyword", by.y = "key") %>%
arrange(desc(freq)) %>%
#group_by(keyword,freq) %>% summari
distinct(keyword,freq)
# verbs$verb[verbs$character=="QP"]
verb_phrases <- lemmed %>%
group_by(start, end) %>%
summarise(string = c(word)) %>%
rowwise()
nest_by(ngram, pattern, start, end)
Example with gcodes
freq %>%
group_by(character) %>% arrange(desc(n)) %>% slice(1:12) %>% ungroup() %>%
#mutate(noun = reorder_within(lemma.x, by = n, within = character),) %>%
ggplot(aes(x = lemma, y = n, fill = character)) +
geom_col(show.legend = FALSE) +
labs(x = "Nouns", y = "frequency") +
#facet_wrap(~character, ncol = 6, scales = "free_y") +
coord_flip() +
#scale_x_reordered() +
facet_grid(~character)+
theme(axis.text.y = element_text(size = 6))

t5vup5 <- freq %>% select(verb,lemma,character,n,freq) %>% distinct() %>% group_by(character) %>% arrange(desc(freq)) %>% slice(1:5) %>% ungroup() t5vup5
undata2 <- pre_pro_rep %>%
unnest_tokens(bigram,text,token = "ngrams", n=2) #%>%
#mutate(bigram = bigram %>% str_remove_all("[^[:alnum:]]")) %>%
undata1 <- pre_pro_rep %>%
unnest_tokens(word,text,token = "ngrams", n=1) %>%
mutate(word = word %>% str_remove_all("[^[:alnum:]]")) %>%
mutate(word = word %>% str_remove_all(rem_dig)) %>%
mutate(word = word %>% str_remove_all("null")) %>%
filter(!is.na(word)) %>%
anti_join(stop_words, by = "word")
bigrams_separated <- undata2 %>% separate(bigram, c("word1", "word2"), sep = " ")
bigrams_filtered <- bigrams_separated %>% filter(!word1 %in% stop_words$word) %>% filter(!word2 %in% stop_words$word)
# new bigram counts:
bigram_counts <- bigrams_filtered %>% count(word1, word2, sort = TRUE)
bigrams_united <- bigrams_filtered %>% unite(bigram, word1, word2, sep = " ")
bigrams_united %<>% add_count(X,bigram) %>% bind_tf_idf(term = bigram, document = X, n = n)
words <- undata1 %>% add_count(X,word) %>% bind_tf_idf(term = word, document = X, n = n)
bigrams_united %>% count(bigram, wt = tf_idf, sort = TRUE) %>% head(25)
top_by_g <- bigrams_united %>% group_by(gcode) %>% count(bigram, wt = tf_idf, sort = TRUE, name = "tf_idf") %>% dplyr::slice(1:12) %>% ungroup()
top_by_g <- words %>% group_by(gcode) %>% count(word, wt = tf_idf, sort = TRUE, name = "tf_idf") %>% dplyr::slice(1:5) %>% ungroup()
top_by_y <- bigrams_united %>% group_by(rep_year) %>% count(bigram, wt = tf_idf, sort = TRUE, name = "tf_idf") %>% dplyr::slice(1:12) %>% ungroup()
# top bigrams in each g_code
top_by_g %>% mutate(bigram = reorder_within(bigram, by = tf_idf, within = gcode)) %>%
ggplot(aes(x = bigram, y = tf_idf, fill = gcode)) +
geom_col(show.legend = FALSE) +
labs(x = NULL, y = "tf-idf") +
facet_wrap(~gcode, ncol = 3, scales = "free") +
coord_flip() +
scale_x_reordered() +
theme(axis.text.y = element_text(size = 6))
top_by_g %>% mutate(word = reorder_within(word, by = tf_idf, within = gcode)) %>%
ggplot(aes(x = word, y = tf_idf, fill = gcode)) +
geom_col(show.legend = FALSE) +
labs(x = NULL, y = "tf-idf") +
facet_wrap(~gcode, ncol = 3, scales = "free") +
coord_flip() +
scale_x_reordered() +
theme(axis.text.y = element_text(size = 8))
library(textdata)
library(recipes)
library(tidymodels)
library(textrecipes)
library(themis)
library(tune)
library(glmnet)
library(ranger)
mdata <- ocpt2 %>% ungroup() %>% select(gcode,text)
ocpt2 %>% ungroup() %>% select(gcode,text) %>% count(gcode)
#glove6b <- embedding_glove6b(dimensions = 100)
set.seed(1234)
rem_punct <- regex("[[:punct:]]")
rem_dig <- regex("[[:digit:]]")
mdata %<>% mutate(text=str_squish(text),
text=str_remove_all(text,rem_punct),
text=str_remove_all(text,rem_dig))
mdata %>% group_by(gcode) %>% count(sort = T)# %>% slice(1:8) %>% ungroup() # %>% ggplot(aes(x = gcode, y = n)) + geom_col()
mdata %<>% filter(gcode %in% c("401","403","404", "407", "405","413","414","417","416","999"))
# mdata %<>% filter(!gcode %in% c("409","410","411"))
# mdata %<>% drop_na()
mdata %<>% mutate(gcode=as.factor(gcode))
#downsampling
mdata %>% filter(gcode %in% c("999"))
no_label_index <- which(mdata$gcode==999)
# labeled_index <- which(!mdata$gcode==999)
random_indexes <- sample(1:length(no_label_index), length(no_label_index)-300, replace=F)
# random_downsample <- no_label_index[-c(random_indexes)]
mdata <-mdata[-c(no_label_index[c(random_indexes)]),]
mdata %>% count(gcode)
write.csv(mdata, "mdata_2.csv")
tidy_split <- initial_split(mdata, strata = gcode, prop = 0.7)
train_data <- training(tidy_split)
test_data <- testing(tidy_split)
tidy_split
<Analysis/Assess/Total>
<1277/552/1829>
train_data <- recipe(gcode~., data = train_data) %>% themis::step_upsample(gcode) %>% prep() %>% juice()
train_data %<>% mutate(text=as.character(text))
data_res <- train_data %>% vfold_cv(strata = gcode, v = 10, repeats = 3)
data_res <- vfold_cv(train_data)
tf_idf_rec <- recipe(gcode ~ ., data = train_data) %>%
step_tokenize(text) %>%
step_stem(text) %>%
step_stopwords(text) %>%
step_tokenfilter(text, max_tokens = 1000) %>%
step_tfidf(all_predictors())
tf_idf_data <- tf_idf_rec %>% prep() %>% juice()
hash_rec <- recipe(gcode~., data = train_data) %>%
step_tokenize(text) %>%
step_stem(text) %>%
step_stopwords(text) %>%
step_tokenfilter(text, max_tokens = 1000) %>%
step_texthash(text, num_terms = 100)
hash_rec %>% prep() %>% juice()
NA
model_lg <- multinom_reg() %>%
set_args(penalty=tune(), mixture=NULL) %>%
set_engine("glmnet") %>%
set_mode("classification")
model_rf <- rand_forest() %>%
set_engine("ranger", importance = "impurity") %>%
set_mode("classification")
logistic_grid <- grid_regular(parameters(model_lg), levels = 3)
model_control <- control_grid(save_pred = TRUE)
model_metrics <- metric_set(accuracy, roc_auc)
linear_tf_res <- tune_grid(model_lg, tf_idf_rec, grid = logistic_grid, control = model_control, metrics = model_metrics, resamples = data_res)
linear_hash_res <- tune_grid(model_lg, hash_rec, grid = logistic_grid, control = model_control, metrics = model_metrics, resamples = data_res)
workflow_general_tf <- workflow() %>% add_recipe(tf_idf_rec)
workflow_lg_tf <- workflow_general_tf %>% add_model(model_lg)
workflow_rf_tf <- workflow_general_tf %>% add_model(model_rf)
workflow_general_hash <- workflow() %>% add_recipe(hash_rec)
workflow_lg_hash <- workflow_general_hash %>% add_model(model_lg)
workflow_rf_hash <- workflow_general_hash %>% add_model(model_rf)
linear_tf_res %>% autoplot()

best_param_linear_tf_res <- linear_tf_res %>% select_best(metric = 'accuracy')
best_param_linear_tf_res
workflow_final_lg_tf <- workflow_lg_tf %>%
finalize_workflow(parameters = best_param_linear_tf_res)
log_res_tf <- workflow_final_lg_tf %>%
fit_resamples(resamples = data_res,
metrics = metric_set(recall, precision, f_meas, accuracy, kap, roc_auc, sens), control = control_resamples(save_pred = TRUE))
log_res_tf %>% collect_metrics(summarize = TRUE)
linear_hash_res %>% autoplot()

best_param_linear_hash_res <- linear_hash_res %>% select_best(metric = 'accuracy')
best_param_linear_hash_res
workflow_final_lg_hash <- workflow_lg_hash %>%
finalize_workflow(parameters = best_param_linear_hash_res)
log_res_hash <- workflow_final_lg_hash %>%
fit_resamples( resamples = data_res,
metrics = metric_set(recall, precision, f_meas, accuracy, kap, roc_auc, sens), control = control_resamples(save_pred = TRUE))
log_res_hash %>% collect_metrics(summarize = TRUE)
rf_res_hash <- workflow_rf_hash %>%
fit_resamples(resamples = data_res,
metrics = metric_set(recall, precision, f_meas, accuracy, kap, roc_auc, sens),
control = control_resamples( save_pred = TRUE))
rf_res_hash %>% collect_metrics(summarize = TRUE)
NA
rf_res_tf <- workflow_rf_tf %>%
fit_resamples(resamples = data_res,
metrics = metric_set(recall, precision, f_meas, accuracy, kap, roc_auc, sens),
control = control_resamples( save_pred = TRUE))
rf_res_tf %>% collect_metrics(summarize = TRUE)
NA
log_metrics_tf <- log_res_tf %>% collect_metrics(summarise = TRUE) %>% mutate(model = "Logistic Regression TF-idf")
log_metrics_hash <- log_res_hash %>% collect_metrics(summarise = TRUE) %>% mutate(model = "Logistic Regression Hash")
rf_metrics_tf <- rf_res_tf %>% collect_metrics(summarise = TRUE) %>% mutate(model = "Random Forest TF-idf")
rf_metrics_hash <- rf_res_hash %>% collect_metrics(summarise = TRUE) %>% mutate(model = "Random Forest Hash")
model_compare <- bind_rows(
log_metrics_tf,
log_metrics_hash,
rf_metrics_tf,
rf_metrics_hash)
rf_stat1 <- rf_res_tf %>% collect_metrics(summarize = TRUE)
rf_stat1
model_comp <- model_compare %>%
select(model, .metric, mean, std_err) %>%
pivot_wider(names_from = .metric, values_from = c(mean, std_err))
model_comp %>%
arrange(mean_f_meas) %>%
mutate(model = fct_reorder(model, mean_f_meas)) %>%
ggplot(aes(model, mean_f_meas, fill=model)) +
geom_col() + coord_flip() +
scale_fill_brewer(palette = "YlGn") +
geom_text(size = 3, aes(label = round(mean_f_meas, 2), y = mean_f_meas + 0.08), vjust = 1)

rf_pred_tf <- rf_res_tf %>%
collect_predictions()
rf_pred_tf %>% conf_mat(gcode, .pred_class)
Truth
Prediction 401 403 404 405 407 413 414 416 417 999
401 171 8 8 7 0 0 0 0 0 7
403 18 203 3 3 0 3 1 2 0 3
404 19 3 216 2 0 0 2 0 0 2
405 10 4 2 213 0 0 0 0 0 5
407 1 4 0 1 233 0 1 0 0 1
413 6 0 1 0 0 221 0 0 0 10
414 2 1 2 1 0 0 228 1 0 5
416 1 1 0 0 0 2 0 228 1 1
417 1 0 0 0 0 0 0 0 230 3
999 4 9 1 6 0 7 1 2 2 196
rf_pred_tf %>% conf_mat(gcode, .pred_class) %>% autoplot(type = "heatmap")

last_fit_rf <- last_fit(workflow_rf_tf,
split = tidy_split,
metrics = metric_set(recall, precision, f_meas, accuracy, kap, roc_auc, sens))
rf_stat2 <- last_fit_rf %>% collect_metrics()
rf_stat2
last_fit_rf %>% collect_predictions() %>% conf_mat(gcode, .pred_class) %>% autoplot(type = "heatmap")

myt <- rf_stat1 %>% left_join(rf_stat2, by=".metric") %>% select(.metric, mean, std_err, .estimate)
myt
NA
library(stargazer)
library(xtable)
#stargazer(myt, type = "latex", out = "models.tex")
stargazer(myt, type = "text")
print(xtable(myt, type = "latex"), file = "myt.tex")
nyt <- ocpt2 %>% group_by(gcode) %>% count()
library(parsnip)
library(recipes)
library(workflows)
library(modeldata)
prod_ds <- read.csv("listed_danish_companies_text_pure.csv") %>% select(-X)
tf_idf_rec_production <- recipe(gcode ~ ., data = prod_ds) %>%
step_tokenize(text) %>%
step_stem(text) %>%
step_stopwords(text) %>%
step_tokenfilter(text, max_tokens = 1000) %>%
step_tfidf(all_predictors())
tf_idf_prod <- tf_idf_rec_production %>% prep() %>% juice()
model_rf <- rand_forest() %>%
set_engine("ranger", importance = "impurity", num.threads = parallel::detectCores()) %>%
set_mode("classification")
wf_rf_tf <- workflow() %>%
add_recipe(tf_idf_rec) %>%
add_model(model_rf)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQpsaWJyYXJ5KHBkZnRvb2xzKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShzdHJpbmdpKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KGlncmFwaCkKbGlicmFyeShnZ3JhcGgpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXJzbmlwKQpsaWJyYXJ5KHdvcmtmbG93cykKYGBgCgojIyBMb2FkaW5nIGRhdGEKYGBge3J9Cm9jcHQgPC0gcmVhZFJEUygib3JsaXN0X2NvZ2VzX3BhZ2VzX3RleHRfdW5uZXN0ZWRfZmluYWwucmRzIikKb2NwdCAlPiUgZ2xpbXBzZSgpCgp3cml0ZS5jc3Yob2NwdCwgIm9jcHR1LmNzdiIpCgpvY3B0ICU+JSBncm91cF9ieShmdWxscGF0aCkgJT4lIGNvdW50KCkKYGBgCiMjIFByZXBhcmUgc2V0cwpgYGB7cn0KCiNmb3IgbW9kZWxsaW5nCm9jcHQyIDwtIG9jcHQgJT4lIHVuZ3JvdXAoKSU+JSBkaXN0aW5jdChmdWxscGF0aCwgcGRmX3BhZ2UsIC5rZWVwX2FsbCA9IFRSVUUpCgojZm9yIHRleHQgbWluaW5nCm9jcHQzIDwtIG9jcHQgJT4lIGZpbHRlcighZ2NvZGU9PSI5OTkiKSAlPiUgdW5ncm91cCgpICU+JSBkaXN0aW5jdChmdWxscGF0aCwgcGRmX3BhZ2UsIC5rZWVwX2FsbCA9IFRSVUUpCm9jcHQzICU8PiUgbXV0YXRlKGRvY19pZD1wYXN0ZTAob3JpZ19pZCwgIiwgIiwgZ2NvZGUpKQpgYGAKCiMjIEFubm90YXRpbmcgdGV4dApgYGB7cn0KbGlicmFyeSh1ZHBpcGUpCnVkbW9kZWwgPC0gdWRwaXBlX2xvYWRfbW9kZWwoZmlsZSA9ICJlbmdsaXNoLWV3dC11ZC0yLjUtMTkxMjA2LnVkcGlwZSIpCgp1cCA8LSB1ZHBpcGVfYW5ub3RhdGUodWRtb2RlbCwgeCA9IG9jcHQzJHRleHQsIGRvY19pZCA9IG9jcHQzJGRvY19pZCkKdXAgPC0gYXMuZGF0YS5mcmFtZSh1cCkKYGBgCgoKIyMgTWFraW5nIGEgbGlzdCBvZiB2ZXJicyBmcm9tIGF2YWlsYWJsZSB0ZXh0cwpgYGB7cn0KCnN0YXRzIDwtIHN1YnNldCh1cCwgdXBvcyAlaW4lIGMoIlZFUkIiKSkgCnN0YXRzIDwtIHR4dF9mcmVxKHN0YXRzJGxlbW1hKQpzdGF0cyAlPiUgaGVhZCg1MCkKd3JpdGUuY3N2KHN0YXRzLCAidmVyYnMuY3N2IikKCmBgYAojIyBVcGxvYWRpbmcgYSBsaXN0IG9mIGdyb3VwZWQgdmVyYnMKClRvIGZpbmQgc3lub25pbXMgZm9yIEVuZ2xpc2ggd29yZHMgd2UgY2FuIHVzZSB0aGUgV29yZE5ldCBhbmQgaXRzIFIgd3JhcHBlciBpbiB0aGUgd29yZG5ldCBwYWNrYWdlLiAoaHR0cHM6Ly9iZXJuaGFyZGxlYXJucy5ibG9nc3BvdC5jb20vMjAxNy8wNC9jbGVhbmluZy13b3Jkcy13aXRoLXItc3RlbW1pbmcuaHRtbCkKYGBge3J9CnZlcmJzPC1yZWFkLmNzdigidmVyYnNfZ3JvdXBlZC5jc3YiKQoKdmVyYnMgJTw+JSBtdXRhdGUodmVyYj1zdHJfdHJpbSh2ZXJiKSkKdmVyYnMgJTw+JSB1bmlxdWUoKQpgYGAKCmBgYHtyfQojdmVyYnNfcXAgPC0gdmVyYnMgJT4lIGZpbHRlcihjaGFyYWN0ZXI9PSJRTiIpICU+JSBzZWxlY3QodmVyYikKCnVwMiA8LSB1cCAlPiUgc3Vic2V0KHVwb3MgJWluJSBjKCJWRVJCIikgJiBkZXBfcmVsICVpbiUgYygicm9vdCIpKQp1cDIgJTw+JSBzdWJzZXQobGVtbWEgJWluJSBhcy52ZWN0b3IodmVyYnMkdmVyYikpCnVwMiAlPD4lIG1lcmdlKHR4dF9mcmVxKHVwMiRsZW1tYSksIGJ5Lng9ICJsZW1tYSIsIGJ5LnkgPSAia2V5IikKIyB1cDIgJTw+JSBjb3VudChsZW1tYSkgJT4lICBtdXRhdGUoZnJlcSA9IG4gLyBzdW0obikpICU+JSAgIGFycmFuZ2UoZGVzYyhuKSkKCnVwMiAgJTw+JSAgbGVmdF9qb2luKHZlcmJzLCBieT1jKCJsZW1tYSI9InZlcmIiKSkKdXAyICU8PiUgZGlzdGluY3QoKQp1cDIgJTw+JSBzZXBhcmF0ZShkb2NfaWQsIGMoImRvYyIsICJnY29kZSIpLCBzZXAgPSAiLCAiKQojIHZlcmJzICU8PiUgbWVyZ2UodXAyLCBieS54ID0gInZlcmIiLCBieS55PSJsZW1tYSIpCgpgYGAKCmBgYHtyfQp1cDIgJT4lCiAgZGlzdGluY3QobGVtbWEsIC5rZWVwX2FsbCA9IFQpICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSBhcnJhbmdlKGRlc2MoZnJlcSkpICU+JSBzbGljZSgxOjEyKSAlPiUgdW5ncm91cCgpICU+JSAKICBtdXRhdGUodmVyYiA9IHJlb3JkZXJfd2l0aGluKGxlbW1hLCBieSA9IGZyZXEsIHdpdGhpbiA9IGNoYXJhY3RlcikpICU+JQogIGdncGxvdChhZXMoeCA9IHZlcmIsIHkgPSBmcmVxLCBmaWxsID0gY2hhcmFjdGVyKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgbGFicyh4ID0gIlZlcmJzIiwgeSA9ICJmcmVxdWVuY3kiKSArCiAgICBmYWNldF93cmFwKH5jaGFyYWN0ZXIsIG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX3hfcmVvcmRlcmVkKCkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKQpgYGAKCgpgYGB7cn0KCnVwMiAlPiUgCiAgZGlzdGluY3QobGVtbWEsIC5rZWVwX2FsbCA9IFQpICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSBzdW1tYXJpemUoc3VtPXN1bShmcmVxKSkgJT4lICNhcnJhbmdlKGRlc2Moc3VtKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNoYXJhY3RlciwgeSA9IHN1bSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAic3VtIixzaG93LmxlZ2VuZCA9IEZBTFNFKQoKYGBgCgoKYGBge3J9Cgp1cDIgJT4lIAogIGdyb3VwX2J5KGdjb2RlLGNoYXJhY3RlcikgJT4lIGNvdW50KGxlbW1hKSAlPiUgc3VtbWFyaXplKHN1bT1zdW0obiksIC5ncm91cHMgPSAia2VlcCIpICU+JQogIG11dGF0ZShjaGFyYWN0ZXIgPSByZW9yZGVyX3dpdGhpbihjaGFyYWN0ZXIsIGJ5ID0gc3VtLCB3aXRoaW4gPSBnY29kZSkpICU+JQogIGdncGxvdChhZXMoeCA9IGNoYXJhY3RlciwgeSA9IHN1bSwgZmlsbCA9IGdjb2RlKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgbGFicyh4ID0gIlZlcmJzIiwgeSA9ICJmcmVxdWVuY3kiKSArCiAgICBmYWNldF93cmFwKH5nY29kZSwgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfeF9yZW9yZGVyZWQoKSArCiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNikpCmBgYApgYGB7cn0KdmVyYl9waHJhc2Vfc2ltcCA8LSAiKChBfE4pKk4oUCtEKihBfE4pKk4pKlAqKE18VikqVihNfFYpKnwoTXxWKSpWKE18VikqRCooQXxOKSpOKFArRCooQXxOKSpOKSp8KE18VikqVihNfFYpKihQK0QqKEF8TikqTikrfChBfE4pKk4oUCtEKihBfE4pKk4pKlAqKChNfFYpKlYoTXxWKSpEKihBfE4pKk4oUCtEKihBfE4pKk4pKnwoTXxWKSpWKE18VikqKFArRCooQXxOKSpOKSspKSIgIyBTaW1wbGUgdmVyYiBQaHJhc2UKdmVyYl9waHJhc2Vfd2l0aF9jYyA8LSAiKCgoQShDQSkqfE4pKk4oKFAoQ1ApKikrKEQoQ0QpKikqKEEoQ0EpKnxOKSpOKSooQyhEKENEKSopKihBKENBKSp8TikqTigoUChDUCkqKSsoRChDRCkqKSooQShDQSkqfE4pKk4pKikqKShQKENQKSopKihNKENNKSp8VikqVihNKENNKSp8VikqKEMoTShDTSkqfFYpKlYoTShDTSkqfFYpKikqfChNKENNKSp8VikqVihNKENNKSp8VikqKEMoTShDTSkqfFYpKlYoTShDTSkqfFYpKikqKEQoQ0QpKikqKChBKENBKSp8TikqTigoUChDUCkqKSsoRChDRCkqKSooQShDQSkqfE4pKk4pKihDKEQoQ0QpKikqKEEoQ0EpKnxOKSpOKChQKENQKSopKyhEKENEKSopKihBKENBKSp8TikqTikqKSopfChNKENNKSp8VikqVihNKENNKSp8VikqKEMoTShDTSkqfFYpKlYoTShDTSkqfFYpKikqKChQKENQKSopKyhEKENEKSopKihBKENBKSp8TikqTikrfCgoQShDQSkqfE4pKk4oKFAoQ1ApKikrKEQoQ0QpKikqKEEoQ0EpKnxOKSpOKSooQyhEKENEKSopKihBKENBKSp8TikqTigoUChDUCkqKSsoRChDRCkqKSooQShDQSkqfE4pKk4pKikqKShQKENQKSopKigoTShDTSkqfFYpKlYoTShDTSkqfFYpKihDKE0oQ00pKnxWKSpWKE0oQ00pKnxWKSopKihEKENEKSopKigoQShDQSkqfE4pKk4oKFAoQ1ApKikrKEQoQ0QpKikqKEEoQ0EpKnxOKSpOKSooQyhEKENEKSopKihBKENBKSp8TikqTigoUChDUCkqKSsoRChDRCkqKSooQShDQSkqfE4pKk4pKikqKXwoTShDTSkqfFYpKlYoTShDTSkqfFYpKihDKE0oQ00pKnxWKSpWKE0oQ00pKnxWKSopKigoUChDUCkqKSsoRChDRCkqKSooQShDQSkqfE4pKk4pKykpIiAjIFZlcmIgcGhyYXNlIHdpdGggY29vcmRpbmF0aW9uIGNvbmp1bmN0aW9uCmBgYAoKYGBge3J9Cgp1cDMgPC0gdXAgJT4lIHN1YnNldChzZW50ZW5jZSAlaW4lIHVwMiRzZW50ZW5jZSkKdXAzICU8PiUgc2VwYXJhdGUoZG9jX2lkLCBjKCJkb2MiLCAiZ2NvZGUiKSwgc2VwID0gIiwgIikKCnVwMyAlPD4lIG11dGF0ZShwaHJhc2VfdGFnPWFzX3BocmFzZW1hY2hpbmUodXBvcyx0eXBlPSJ1cG9zIikpCgp2ZXJiX3BocmFzZXMgPC0ga2V5d29yZHNfcGhyYXNlcyh1cDMkcGhyYXNlX3RhZywgdGVybSA9IHVwMyR0b2tlbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9IHZlcmJfcGhyYXNlX3NpbXAsIGlzX3JlZ2V4ID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmdyYW1fbWF4ID0gNywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV0YWlsZWQgPSBUUlVFKQoKaGVhZChzb3J0KHRhYmxlKHZlcmJfcGhyYXNlcyRrZXl3b3JkKSwgZGVjcmVhc2luZz1UUlVFKSwgMjApCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KHRleHRzdGVtKQp2ZXJiX3BocmFzZXMyIDwtdmVyYl9waHJhc2VzCgpsZW1tZWQgPC0gdmVyYl9waHJhc2VzICU+JSB1bm5lc3RfdG9rZW5zKHdvcmQsa2V5d29yZCx0b2tlbiA9ICJuZ3JhbXMiLCBuPTEpIApsZW1tZWQgJTw+JSBtdXRhdGUobGVtbWE9bGVtbWF0aXplX3dvcmRzKHdvcmQsIGRpY3Rpb25hcnkgPSBsZXhpY29uOjpoYXNoX2xlbW1hcykpCmxlbW1lZF9zcyA8LSBsZW1tZWQgJT4lIHN1YnNldChsZW1tYSAlaW4lIHZlcmJzJHZlcmJbdmVyYnMkY2hhcmFjdGVyPT0iUVAiXSkKdmVyYl9waHJhc2VzMiAlPD4lIHN1YnNldChzdGFydCAlaW4lIGxlbW1lZF9zcyRzdGFydCAmIGVuZCAlaW4lIGxlbW1lZF9zcyRlbmQpCgoKdmVyYl9waHJhc2VzMiAlPiUgCiAgZmlsdGVyKG5ncmFtPj0zKSAlPiUKICBtZXJnZSh0eHRfZnJlcSh2ZXJiX3BocmFzZXMyJGtleXdvcmQpLCBieS54PSAia2V5d29yZCIsIGJ5LnkgPSAia2V5IikgJT4lIAogIGFycmFuZ2UoZGVzYyhmcmVxKSkgJT4lIAogICNncm91cF9ieShrZXl3b3JkLGZyZXEpICU+JSBzdW1tYXJpCiAgZGlzdGluY3Qoa2V5d29yZCxmcmVxKQoKIyB2ZXJicyR2ZXJiW3ZlcmJzJGNoYXJhY3Rlcj09IlFQIl0KCmBgYAoKCmBgYHtyfQp2ZXJiX3BocmFzZXMgPC0gbGVtbWVkICU+JQogIGdyb3VwX2J5KHN0YXJ0LCBlbmQpICU+JQogIHN1bW1hcmlzZShzdHJpbmcgPSBjKHdvcmQpKSAlPiUKICByb3d3aXNlKCkKCiAgbmVzdF9ieShuZ3JhbSwgcGF0dGVybiwgc3RhcnQsIGVuZCkKYGBgCgoKCgojIyBUcnlpbmcgdG8gZmluZCBjb29jY3VycmVuY2VzIGFtb3VuZyBzbGVjdGVkIHZlcmJzIGFuZCBub3VucyDigJQgc29tZSB1bmNlcnRhaW50eSBpbnRyb2R1Y2VkIHNpbmNlIGxlbW1hIGNhbiBiZSBib3RoIG5vdW4gYW5kIGEgdmVyYi4KYGBge3J9CmNvb2MgPC0gY29vY2N1cnJlbmNlKHggPSBzdWJzZXQodXAzLCB1cG9zICVpbiUgYygiTk9VTiIsICJWRVJCIikpLCAKICAgICAgICAgICAgICAgICAgICAgdGVybSA9ICJsZW1tYSIsIAogICAgICAgICAgICAgICAgICAgICBncm91cCA9IGMoImRvYyIsICJnY29kZSIsICJwYXJhZ3JhcGhfaWQiLCAic2VudGVuY2VfaWQiKSkKY29vYyAlPD4lIHN1YnNldCh0ZXJtMSAlaW4lIHZlcmJzJHZlcmIgfCB0ZXJtMiAlaW4lIHZlcmJzJHZlcmIpIApjb29jICU+JSBzdHIoKQpgYGAKCgpgYGB7cn0Kd29yZG5ldHdvcmsgPC0gaGVhZChjb29jLCA1MCkKd29yZG5ldHdvcmsgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKHdvcmRuZXR3b3JrKQpnZ3JhcGgod29yZG5ldHdvcmssIGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluayhhZXMod2lkdGggPSBjb29jLCBlZGdlX2FscGhhID0gY29vYyksIGVkZ2VfY29sb3VyID0gImxpZ2h0Ymx1ZSIpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgY29sID0gImJsdWUiLCBzaXplID0gNCkgKwogIHRoZW1lX2dyYXBoKGJhc2VfZmFtaWx5ID0gIlNhbnMgU2VyaWYiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgbGFicyh0aXRsZSA9ICJDb29jY3VycmVuY2VzIHdpdGhpbiBzZW50ZW5jZSIsIHN1YnRpdGxlID0gIk5vdW5zICYgVmVyYnMiKQoKYGBgCiMjIE1lcmdpbmcgZG9uZSBiYWRseQpgYGB7cn0KdGVtcGRzPC11cDIgJT4lIHNlbGVjdChkb2MsIGdjb2RlLCBwYXJhZ3JhcGhfaWQsIHNlbnRlbmNlX2lkLCBmcmVxLCBmcmVxX3BjdCwgbGVtbWEsIGNoYXJhY3RlcikgCgp0ZW1wZHMgPC0gbGVmdF9qb2luKHVwMywgdGVtcGRzLCBieT1jKCJkb2MiLCAiZ2NvZGUiLCAicGFyYWdyYXBoX2lkIiwgInNlbnRlbmNlX2lkIikpCgp0ZW1wZHMgJTw+JSBkaXN0aW5jdChkb2MsIGdjb2RlLCBwYXJhZ3JhcGhfaWQsIHNlbnRlbmNlX2lkLCB0b2tlbl9pZCwgLmtlZXBfYWxsID0gVCkKYGBgCgoKIyMgVG9wIDUgdmVyYnMgaW4gZXZlcnkgdmVyYiBncm91cApgYGB7cn0KdDV2IDwtIHVwMiAlPiUgCiAgc2VsZWN0KGxlbW1hLGNoYXJhY3RlcixmcmVxKSAlPiUKICBkaXN0aW5jdCgpICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSAKICBhcnJhbmdlKGRlc2MoZnJlcSkpICU+JSAKICBzbGljZSgxOjIpICU+JSAKICB1bmdyb3VwKCkKdDV2CmBgYAoKIyMgTW9zdCBjb29jY3VyZWQgbm91bnMgd2l0aCB2ZXJicyBieSBjaGFyYWN0ZXIgaW4gNDAzIGNvZGUKCmBgYHtyfQpmcmVxIDwtIHRlbXBkcyAlPiUKICBmaWx0ZXIoZ2NvZGU9PSI0MDMiKSAlPiUgCiAgc3Vic2V0KGxlbW1hLnkgJWluJSB0NXYkbGVtbWEgJiB1cG9zICVpbiUgIk5PVU4iKSAlPiUKICBncm91cF9ieShsZW1tYS55KSAlPiUgY291bnQobGVtbWEueCkgJT4lIG11dGF0ZShmcmVxID0gbiAvIHN1bShuKSkgJT4lIHVuZ3JvdXAoKQpmcmVxCmZyZXEgJT4lIAogIG1lcmdlKHQ1diAlPiUgc2VsZWN0KGxlbW1hLGNoYXJhY3RlciksIGJ5Lng9ImxlbW1hLnkiLCBieS55PSJsZW1tYSIpICU+JSAKICAjZ3JvdXBfYnkoY2hhcmFjdGVyKSAlPiUgY291bnQoKQogIGdyb3VwX2J5KGxlbW1hLnkpICU+JSBhcnJhbmdlKGRlc2MobikpICU+JSBzbGljZSgxOjUpICU+JSB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZShsZW1tYS55ID0gc3RyX2MoIigiLGNoYXJhY3RlciwiKSAiLGxlbW1hLnksIHNlcD0iIiksCiAgICAgICAgIG5vdW4gPSByZW9yZGVyX3dpdGhpbihsZW1tYS54LCBieSA9IG4sIHdpdGhpbiA9IGxlbW1hLnkpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBub3VuLCB5ID0gbiwgZmlsbCA9IGNoYXJhY3RlcikpICsKICAgIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICAgIGxhYnMoeCA9ICJOb3VucyIsIHkgPSAiZnJlcXVlbmN5IikgKwogICAgZmFjZXRfd3JhcCh+bGVtbWEueSwgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfeF9yZW9yZGVyZWQoKSArCiAgICAjZmFjZXRfZ3JpZCh+Y2hhcmFjdGVyKSsKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSkKCmBgYAoKIyMgVG9wIE5vdW5zIGNvb2NjdXJlZCB3aXRoIHZlcmJzIGJ5IGV2ZXJ5IHZlcmItY2hhcmFjdGVyCmBgYHtyfQogCnRlbXBkcyAlPiUKICBzdWJzZXQobGVtbWEueSAlaW4lIHQ1diRsZW1tYSAmIHVwb3MgJWluJSAiTk9VTiIpICU+JQogIGdyb3VwX2J5KGdjb2RlLGNoYXJhY3RlcikgJT4lIGNvdW50KGxlbW1hLngpICU+JSBtdXRhdGUoZnJlcSA9IG4gLyBzdW0obikpICU+JSB1bmdyb3VwKCkgJT4lIAogIGZpbHRlcihnY29kZT09IjQwMSIpICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSBhcnJhbmdlKGRlc2MobikpICU+JSBzbGljZSgxOjEyKSAlPiUgdW5ncm91cCgpICU+JQogICNtdXRhdGUobm91biA9IHJlb3JkZXJfd2l0aGluKGxlbW1hLngsIGJ5ID0gbiwgd2l0aGluID0gY2hhcmFjdGVyKSwpICU+JQogIGdncGxvdChhZXMoeCA9IGxlbW1hLngsIHkgPSBuLCBmaWxsID0gY2hhcmFjdGVyKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgbGFicyh4ID0gIk5vdW5zIiwgeSA9ICJmcmVxdWVuY3kiKSArCiAgICAjZmFjZXRfd3JhcCh+Y2hhcmFjdGVyLCBuY29sID0gNiwgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICAjc2NhbGVfeF9yZW9yZGVyZWQoKSArCiAgICBmYWNldF9ncmlkKH5jaGFyYWN0ZXIpKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKQoKYGBgCgoKCiMjIFRyeWluZyBtb3JlIHNlbWFudGljIGFuYWx5c2lzCgoKYGBge3J9CgpsaWJyYXJ5KGlncmFwaCkKbGlicmFyeShnZ3JhcGgpCmxpYnJhcnkoZ2dwbG90MikKcGxvdF9hbm5vdGF0aW9uIDwtIGZ1bmN0aW9uKHgsIHNpemUgPSAzKXsKICBzdG9waWZub3QoaXMuZGF0YS5mcmFtZSh4KSAmIGFsbChjKCJzZW50ZW5jZV9pZCIsICJ0b2tlbl9pZCIsICJoZWFkX3Rva2VuX2lkIiwgImRlcF9yZWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRva2VuIiwgImxlbW1hIiwgInVwb3MiLCAieHBvcyIsICJmZWF0cyIpICVpbiUgY29sbmFtZXMoeCkpKQogIHggPC0geFshaXMubmEoeCRoZWFkX3Rva2VuX2lkKSwgXQogIHggPC0geFt4JHNlbnRlbmNlX2lkICVpbiUgbWluKHgkc2VudGVuY2VfaWQpLCBdCiAgZWRnZXMgPC0geFt4JGhlYWRfdG9rZW5faWQgIT0gMCwgYygidG9rZW5faWQiLCAiaGVhZF90b2tlbl9pZCIsICJkZXBfcmVsIildCiAgZWRnZXMkbGFiZWwgPC0gZWRnZXMkZGVwX3JlbAogIGcgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGVkZ2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2VzID0geFssIGMoInRva2VuX2lkIiwgInRva2VuIiwgImxlbW1hIiwgInVwb3MiLCAieHBvcyIsICJmZWF0cyIpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZCA9IFRSVUUpCiAgZ2dyYXBoKGcsIGxheW91dCA9ICJsaW5lYXIiKSArCiAgICBnZW9tX2VkZ2VfYXJjKGdncGxvdDI6OmFlcyhsYWJlbCA9IGRlcF9yZWwsIHZqdXN0ID0gLTAuMjApLAogICAgICAgICAgICAgICAgICBhcnJvdyA9IGdyaWQ6OmFycm93KGxlbmd0aCA9IHVuaXQoNCwgJ21tJyksIGVuZHMgPSAibGFzdCIsIHR5cGUgPSAiY2xvc2VkIiksCiAgICAgICAgICAgICAgICAgIGVuZF9jYXAgPSBnZ3JhcGg6OmxhYmVsX3JlY3QoIndvcmRzd29yZHN3b3JkcyIpLAogICAgICAgICAgICAgICAgICBsYWJlbF9jb2xvdXIgPSAicmVkIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIGxhYmVsX3NpemUgPSBzaXplKSArCiAgICBnZW9tX25vZGVfbGFiZWwoZ2dwbG90Mjo6YWVzKGxhYmVsID0gdG9rZW4pLCBjb2wgPSAiZGFya2dyZWVuIiwgc2l6ZSA9IHNpemUsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgICBnZW9tX25vZGVfdGV4dChnZ3Bsb3QyOjphZXMobGFiZWwgPSB1cG9zKSwgbnVkZ2VfeSA9IC0wLjM1LCBzaXplID0gc2l6ZSkgKwogICAgdGhlbWVfZ3JhcGgoYmFzZV9mYW1pbHkgPSAiQXJpYWwgTmFycm93IikgKwogICAgbGFicyh0aXRsZSA9ICJ1ZHBpcGUgb3V0cHV0Iiwgc3VidGl0bGUgPSAidG9rZW5pc2F0aW9uLCBwYXJ0cyBvZiBzcGVlY2ggdGFnZ2luZyAmIGRlcGVuZGVuY3kgcmVsYXRpb25zIikKfQoKdXAzWzIzNzoyNTUsXQoKCnBuZygibXlfcGxvdC5wbmciKQoKIyBDb2RlCnBsb3RfYW5ub3RhdGlvbih1cDNbMjM3OjI1NSxdKQoKIyBDbG9zZSBkZXZpY2UKZGV2Lm9mZigpCgpgYGAKCiMjIyBTZWxlY3Rpbmcgd29yZHMgdGhhdCBhcmUgcmVsYXRlZCB0byB0aGUgdmVyYnMgYW5kIGxlYXZpbmcgb25seSBuc3Viaiwgb2JsLCBhZHZjbCwgY2NvbXAKYGBge3J9Cgp1cDUgPC0gdXAzICU+JQogIGdyb3VwX2J5KGRvYywgZ2NvZGUsIHBhcmFncmFwaF9pZCwgc2VudGVuY2VfaWQpICU+JQogIGdyb3VwX21vZGlmeSh+bXV0YXRlKC54LAogICAgICAgICAgICAgICAgICAgICAgIHJvb3RfdG9rX2lkPXN1YnNldCguLGRlcF9yZWw9PSJyb290IikgJT4lIC4kdG9rZW5faWQsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYj1zdWJzZXQoLixkZXBfcmVsPT0icm9vdCIpICU+JSAuJGxlbW1hKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUKICBzdWJzZXQoaGVhZF90b2tlbl9pZD09cm9vdF90b2tfaWR8aGVhZF90b2tlbl9pZD09MCkKCnVwNSAlPD4lIHN1YnNldCghZGVwX3JlbD09InB1bmN0IikKdXA1ICU8PiUgc3Vic2V0KCFsZW1tYT09ImJlIikKdXA1ICU8PiUgbWVyZ2UodmVyYnMsIGJ5Lng9InZlcmIiLCBieS55PSJ2ZXJiIikgJT4lIGRpc3RpbmN0KGRvYywgZ2NvZGUsIHBhcmFncmFwaF9pZCwgc2VudGVuY2VfaWQsIHRva2VuX2lkLCAua2VlcF9hbGwgPSBUKSAjbWVyZ2luZyBxdWVzdGlvbgoKYGBgCgpjaGFuZ2UgZG9jIHRvIGludGVnZXIsIGdldCByaWQgb2YgZHVwbGljYXRlcywgcGxvdCB0b3AgZ3JpIHdpdGggdmVyYnMgYW5kIHRvcCB3b3JkcyBhcyBpIGRpZCBpbiBtb3N0IGNvb2NjdXJlZCBub3Vucy4KYGBge3J9CnVwNSAlPD4lIG11dGF0ZShkb2M9YXMuaW50ZWdlcihkb2MpKQp1cDUgJTw+JSBhcnJhbmdlKGRvYyxnY29kZSxwYXJhZ3JhcGhfaWQsc2VudGVuY2VfaWQpCnVwNSAlPiUgZ3JvdXBfYnkoZGVwX3JlbCkgJT4lIGNvdW50KCkgJT4lIGFycmFuZ2UoZGVzYyhuKSkKdXA1ICU+JQogIGZpbHRlcihkZXBfcmVsICVpbiUgYygicm9vdCIsIm9ibCIsICJuc3ViaiIsICJvYmoiLCAibnN1Ymo6cGFzcyIsICJhdXg6cGFzcyIsICJhZHZjbCIsICJjY29tcCIpKSAlPiUKICBncm91cF9ieShnY29kZSkgJT4lIGNvdW50KCkgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHVuZ3JvdXAoKQpgYGAKCiMjIyBFeGFtcGxlIHdpdGggbnN1YmosIGV0Yy4gTWVhbmluZyB0aGF0IHRoZSBsaW5rIGlzIHRoZSBmb2xsb3dpbmc6ICJzb21ldGhpbmcg4oCUIGRvZXMiLCAib2JsIiwgIm9iaiIsICJuc3ViajpwYXNzIiwgImF1eDpwYXNzIiwgImFkdmNsIiwgImNjb21wIgpgYGB7cn0KCiMjIFN1Yi1zZXR0aW5nIHRoZSBsaXN0IG9mIGRlcGVuZGFibGUgd29yZHMgdG8gbnN1YmosIG9ibCwgb2JqLCBuc3ViajpwYXNzLCBhdXg6cGFzcywgYWR2Y2wsIGNjb21wCmZyZXEgPC0gdXA1ICU+JQogICNmaWx0ZXIoZ2NvZGU9PSI0MDEiKSAlPiUgCiAgZmlsdGVyKGRlcF9yZWwgJWluJSBjKCJuc3ViaiIsICJvYmwiLCAib2JqIiwgIm5zdWJqOnBhc3MiLCAiYXV4OnBhc3MiLCAiYWR2Y2wiLCAiY2NvbXAiKSkgJT4lCiAgbXV0YXRlKGxlbW1hPXN0cl9jKGxlbW1hLCAiICgiLGRlcF9yZWwsIikiLCBzZXAgPSAiIikpICU+JSAKICBncm91cF9ieSh2ZXJiLGNoYXJhY3RlcikgJT4lIGNvdW50KGxlbW1hKSAlPiUgbXV0YXRlKGZyZXEgPSBuIC8gc3VtKG4pKSAlPiUgdW5ncm91cCgpICMlPiUgCiAgI21lcmdlKHVwNSwgYnk9YygidmVyYiIsImxlbW1hIikpICU+JSBkaXN0aW5jdChkb2MsIGdjb2RlLCBwYXJhZ3JhcGhfaWQsIHNlbnRlbmNlX2lkLCB0b2tlbl9pZCwgLmtlZXBfYWxsID0gVCkKCiMjIE1ha2luZyB0aGUgbGlzdCBvZiBmaXZlIHRvcCB2ZXJicyBpbiBldmVyeSBjYXRlZ29yeQp0NXZ1cDUgPC0gdXA1ICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSAKICBjb3VudCh2ZXJiKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKSAlPiUgCiAgc2xpY2UoMTo1KSAlPiUgCiAgdW5ncm91cCgpCnQ1dnVwNQoKCmZyZXEgJT4lIAogIHN1YnNldCh2ZXJiICVpbiUgdDV2dXA1JHZlcmIpICU+JSAjIHRha2luZyBvbmx5IDUgdG9wIHZlcmJzIGluIGV2ZXJ5IGNhdGVnb3J5CiAgZ3JvdXBfYnkodmVyYikgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHNsaWNlKDE6MTApICU+JSB1bmdyb3VwKCkgJT4lICMgdGFraW5nIHVwIHRvIDEwIHdvcmRzIGZvciBldmVyeSB2ZXJiCiAgI2dyb3VwX2J5KGNoYXJhY3RlcikgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHNsaWNlKDE6MTApICU+JSB1bmdyb3VwKCkgJT4lCiAgI2dyb3VwX2J5KHZlcmIpICU+JSBjb3VudCgpICU+JSBhcnJhbmdlKGRlc2MobikpCiAgbXV0YXRlKHZlcmIgPSBzdHJfYygiKCIsY2hhcmFjdGVyLCIpICIsdmVyYiwgc2VwPSIiKSwgIyBhZGRpbmcgY2F0ZWdvcnkgdG8gdmVyYgogICAgICAgICBsZW1tYSA9IHJlb3JkZXJfd2l0aGluKGxlbW1hLCBieSA9IG4sIHdpdGhpbiA9IHZlcmIpKSAlPiUgIyByZW9yZGVyaW5nIHdvcmRzIGluIGV2ZXJ5IGdyb3VwCiAgZ2dwbG90KGFlcyh4ID0gbGVtbWEsIHkgPSBuLCBmaWxsID0gY2hhcmFjdGVyKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBUKSArCiAgICBsYWJzKHggPSAibnN1YmosIG9ibCwgb2JqLCBuc3ViajpwYXNzLCBhdXg6cGFzcywgYWR2Y2wsIGNjb21wIiwgCiAgICAgICAgIHkgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwKICAgICAgICAgdGl0bGUgPSAiRWZmZWN0cyByZWZsZWN0ZWQgaW4gR1JJIFJlcG9ydHMgdW5kZXIgNDAxLTQxOSBjb2RlcyIpICsKICAgIGZhY2V0X3dyYXAofnZlcmIsIG5jb2wgPSA1LCBzY2FsZXMgPSAiZnJlZV95IikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX3hfcmVvcmRlcmVkKCkgKwogICAgI2ZhY2V0X2dyaWQofmNoYXJhY3RlcikrCiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiKSsKICAgIHNjYWxlX2ZpbGxfZGlzY3JldGUobGFiZWxzPWMoIlF1YWxpdHkgbmVnYXRpdmUiLCAiUXVhbGl0eSBuZXV0cmFsIiwgIlF1YWxpdHkgcG9zaXRpdmUiLCAiT3RoZXIiLCAiUXVhbnRpdHkgbmVnYXRpdmUiLCAiUXVhbnRpdHkgcG9zaXRpdmUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iSW1wYWN0IHZlcmIgY2F0ZWdvcnkiKQoKYGBgCgpgYGB7cn0KbXlfY29kZSA8LSA0MTMKbXlfY29kZV9uYW1lIDwtICJMb2NhbCBDb21tdW5pdGllcyIKIyMgU3ViLXNldHRpbmcgdGhlIGxpc3Qgb2YgZGVwZW5kYWJsZSB3b3JkcyB0byBuc3Viaiwgb2JsLCBvYmosIG5zdWJqOnBhc3MsIGF1eDpwYXNzLCBhZHZjbCwgY2NvbXAKZnJlcSA8LSB1cDUgJT4lCiAgZmlsdGVyKGdjb2RlPT1teV9jb2RlKSAlPiUgCiAgZmlsdGVyKGRlcF9yZWwgJWluJSBjKCJuc3ViaiIsICJvYmwiLCAib2JqIiwgIm5zdWJqOnBhc3MiLCAiYXV4OnBhc3MiLCAiYWR2Y2wiLCAiY2NvbXAiKSkgJT4lCiAgbXV0YXRlKGxlbW1hPXN0cl9jKGxlbW1hLCAiICgiLGRlcF9yZWwsIikiLCBzZXAgPSAiIikpICU+JSAKICBncm91cF9ieSh2ZXJiLGNoYXJhY3RlcikgJT4lIGNvdW50KGxlbW1hKSAlPiUgbXV0YXRlKGZyZXEgPSBuIC8gc3VtKG4pKSAlPiUgdW5ncm91cCgpICMlPiUgCiAgI21lcmdlKHVwNSwgYnk9YygidmVyYiIsImxlbW1hIikpICU+JSBkaXN0aW5jdChkb2MsIGdjb2RlLCBwYXJhZ3JhcGhfaWQsIHNlbnRlbmNlX2lkLCB0b2tlbl9pZCwgLmtlZXBfYWxsID0gVCkKCiMjIE1ha2luZyB0aGUgbGlzdCBvZiBmaXZlIHRvcCB2ZXJicyBpbiBldmVyeSBjYXRlZ29yeQp0NXZ1cDUgPC0gdXA1ICU+JSAKICBncm91cF9ieShjaGFyYWN0ZXIpICU+JSAKICBjb3VudCh2ZXJiKSAlPiUgCiAgYXJyYW5nZShkZXNjKG4pKSAlPiUgCiAgc2xpY2UoMTo1KSAlPiUgCiAgdW5ncm91cCgpCnQ1dnVwNQoKCmZyZXEgJT4lIAogIHN1YnNldCh2ZXJiICVpbiUgdDV2dXA1JHZlcmIpICU+JSAjIHRha2luZyBvbmx5IDUgdG9wIHZlcmJzIGluIGV2ZXJ5IGNhdGVnb3J5CiAgZ3JvdXBfYnkodmVyYikgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHNsaWNlKDE6MTApICU+JSB1bmdyb3VwKCkgJT4lICMgdGFraW5nIHVwIHRvIDEwIHdvcmRzIGZvciBldmVyeSB2ZXJiCiAgI2dyb3VwX2J5KGNoYXJhY3RlcikgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHNsaWNlKDE6MTApICU+JSB1bmdyb3VwKCkgJT4lCiAgI2dyb3VwX2J5KHZlcmIpICU+JSBjb3VudCgpICU+JSBhcnJhbmdlKGRlc2MobikpCiAgbXV0YXRlKHZlcmIgPSBzdHJfYygiKCIsY2hhcmFjdGVyLCIpICIsdmVyYiwgc2VwPSIiKSwgIyBhZGRpbmcgY2F0ZWdvcnkgdG8gdmVyYgogICAgICAgICBsZW1tYSA9IHJlb3JkZXJfd2l0aGluKGxlbW1hLCBieSA9IG4sIHdpdGhpbiA9IHZlcmIpKSAlPiUgIyByZW9yZGVyaW5nIHdvcmRzIGluIGV2ZXJ5IGdyb3VwCiAgZ2dwbG90KGFlcyh4ID0gbGVtbWEsIHkgPSBuLCBmaWxsID0gY2hhcmFjdGVyKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBUKSArCiAgICBsYWJzKHggPSAibnN1YmosIG9ibCwgb2JqLCBuc3ViajpwYXNzLCBhdXg6cGFzcywgYWR2Y2wsIGNjb21wIiwgCiAgICAgICAgIHkgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwKICAgICAgICAgdGl0bGUgPSBzdHJfYygiRWZmZWN0cyByZWZsZWN0ZWQgaW4gR1JJIFJlcG9ydHMgdW5kZXIgIiwgbXlfY29kZSwgIiBjb2RlOiAiLCBteV9jb2RlX25hbWUsIHNlcCA9ICIiKSkgKwogICAgZmFjZXRfd3JhcCh+dmVyYiwgbmNvbCA9IDUsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfeF9yZW9yZGVyZWQoKSArCiAgICAjZmFjZXRfZ3JpZCh+Y2hhcmFjdGVyKSsKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgCiAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIpKwogICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShsYWJlbHM9YygiUXVhbGl0eSBuZWdhdGl2ZSIsICJRdWFsaXR5IG5ldXRyYWwiLCAiUXVhbGl0eSBwb3NpdGl2ZSIsICJPdGhlciIsICJRdWFudGl0eSBuZWdhdGl2ZSIsICJRdWFudGl0eSBwb3NpdGl2ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJJbXBhY3QgdmVyYiBjYXRlZ29yeSIpCmBgYAoKCiMjIEV4YW1wbGUgd2l0aCBnY29kZXMKYGBge3J9CmZyZXEgJT4lIAogIGdyb3VwX2J5KGNoYXJhY3RlcikgJT4lIGFycmFuZ2UoZGVzYyhuKSkgJT4lIHNsaWNlKDE6MTIpICU+JSB1bmdyb3VwKCkgJT4lCiAgI211dGF0ZShub3VuID0gcmVvcmRlcl93aXRoaW4obGVtbWEueCwgYnkgPSBuLCB3aXRoaW4gPSBjaGFyYWN0ZXIpLCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGVtbWEsIHkgPSBuLCBmaWxsID0gY2hhcmFjdGVyKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgbGFicyh4ID0gIk5vdW5zIiwgeSA9ICJmcmVxdWVuY3kiKSArCiAgICAjZmFjZXRfd3JhcCh+Y2hhcmFjdGVyLCBuY29sID0gNiwgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICAjc2NhbGVfeF9yZW9yZGVyZWQoKSArCiAgICBmYWNldF9ncmlkKH5jaGFyYWN0ZXIpKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKQpgYGAKCgoKdDV2dXA1IDwtIGZyZXEgJT4lIAogIHNlbGVjdCh2ZXJiLGxlbW1hLGNoYXJhY3RlcixuLGZyZXEpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIGdyb3VwX2J5KGNoYXJhY3RlcikgJT4lIAogIGFycmFuZ2UoZGVzYyhmcmVxKSkgJT4lIAogIHNsaWNlKDE6NSkgJT4lIAogIHVuZ3JvdXAoKQp0NXZ1cDUKCgpgYGB7cn0KdW5kYXRhMiA8LSBwcmVfcHJvX3JlcCAlPiUgCiAgdW5uZXN0X3Rva2VucyhiaWdyYW0sdGV4dCx0b2tlbiA9ICJuZ3JhbXMiLCBuPTIpICMlPiUgCiAgI211dGF0ZShiaWdyYW0gPSBiaWdyYW0gJT4lIHN0cl9yZW1vdmVfYWxsKCJbXls6YWxudW06XV0iKSkgJT4lIAoKdW5kYXRhMSA8LSBwcmVfcHJvX3JlcCAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLHRleHQsdG9rZW4gPSAibmdyYW1zIiwgbj0xKSAlPiUgCiAgbXV0YXRlKHdvcmQgPSB3b3JkICU+JSBzdHJfcmVtb3ZlX2FsbCgiW15bOmFsbnVtOl1dIikpICU+JSAKICBtdXRhdGUod29yZCA9IHdvcmQgJT4lIHN0cl9yZW1vdmVfYWxsKHJlbV9kaWcpKSAlPiUgCiAgbXV0YXRlKHdvcmQgPSB3b3JkICU+JSBzdHJfcmVtb3ZlX2FsbCgibnVsbCIpKSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh3b3JkKSkgJT4lIAogIGFudGlfam9pbihzdG9wX3dvcmRzLCBieSA9ICJ3b3JkIikKCmJpZ3JhbXNfc2VwYXJhdGVkIDwtIHVuZGF0YTIgJT4lIHNlcGFyYXRlKGJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKQpiaWdyYW1zX2ZpbHRlcmVkIDwtIGJpZ3JhbXNfc2VwYXJhdGVkICU+JSBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUgZmlsdGVyKCF3b3JkMiAlaW4lIHN0b3Bfd29yZHMkd29yZCkKCiMgbmV3IGJpZ3JhbSBjb3VudHM6CmJpZ3JhbV9jb3VudHMgPC0gYmlncmFtc19maWx0ZXJlZCAlPiUgY291bnQod29yZDEsIHdvcmQyLCBzb3J0ID0gVFJVRSkKYmlncmFtc191bml0ZWQgPC0gYmlncmFtc19maWx0ZXJlZCAlPiUgdW5pdGUoYmlncmFtLCB3b3JkMSwgd29yZDIsIHNlcCA9ICIgIikKYmlncmFtc191bml0ZWQgJTw+JSBhZGRfY291bnQoWCxiaWdyYW0pICU+JSBiaW5kX3RmX2lkZih0ZXJtID0gYmlncmFtLCBkb2N1bWVudCA9IFgsIG4gPSBuKQoKd29yZHMgPC0gdW5kYXRhMSAlPiUgYWRkX2NvdW50KFgsd29yZCkgJT4lIGJpbmRfdGZfaWRmKHRlcm0gPSB3b3JkLCBkb2N1bWVudCA9IFgsIG4gPSBuKQoKYmlncmFtc191bml0ZWQgJT4lIGNvdW50KGJpZ3JhbSwgd3QgPSB0Zl9pZGYsIHNvcnQgPSBUUlVFKSAlPiUgaGVhZCgyNSkKCnRvcF9ieV9nIDwtIGJpZ3JhbXNfdW5pdGVkICU+JSBncm91cF9ieShnY29kZSkgJT4lIGNvdW50KGJpZ3JhbSwgd3QgPSB0Zl9pZGYsIHNvcnQgPSBUUlVFLCBuYW1lID0gInRmX2lkZiIpICU+JSBkcGx5cjo6c2xpY2UoMToxMikgJT4lIHVuZ3JvdXAoKQoKdG9wX2J5X2cgPC0gd29yZHMgJT4lIGdyb3VwX2J5KGdjb2RlKSAlPiUgY291bnQod29yZCwgd3QgPSB0Zl9pZGYsIHNvcnQgPSBUUlVFLCBuYW1lID0gInRmX2lkZiIpICU+JSBkcGx5cjo6c2xpY2UoMTo1KSAlPiUgdW5ncm91cCgpCgp0b3BfYnlfeSA8LSBiaWdyYW1zX3VuaXRlZCAlPiUgZ3JvdXBfYnkocmVwX3llYXIpICU+JSBjb3VudChiaWdyYW0sIHd0ID0gdGZfaWRmLCBzb3J0ID0gVFJVRSwgbmFtZSA9ICJ0Zl9pZGYiKSAlPiUgZHBseXI6OnNsaWNlKDE6MTIpICU+JSB1bmdyb3VwKCkKCiMgdG9wIGJpZ3JhbXMgaW4gZWFjaCBnX2NvZGUKdG9wX2J5X2cgJT4lIG11dGF0ZShiaWdyYW0gPSByZW9yZGVyX3dpdGhpbihiaWdyYW0sIGJ5ID0gdGZfaWRmLCB3aXRoaW4gPSBnY29kZSkpICU+JQogIGdncGxvdChhZXMoeCA9IGJpZ3JhbSwgeSA9IHRmX2lkZiwgZmlsbCA9IGdjb2RlKSkgKwogICAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9ICJ0Zi1pZGYiKSArCiAgICBmYWNldF93cmFwKH5nY29kZSwgbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX3hfcmVvcmRlcmVkKCkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKQoKCnRvcF9ieV9nICU+JSBtdXRhdGUod29yZCA9IHJlb3JkZXJfd2l0aGluKHdvcmQsIGJ5ID0gdGZfaWRmLCB3aXRoaW4gPSBnY29kZSkpICU+JQogIGdncGxvdChhZXMoeCA9IHdvcmQsIHkgPSB0Zl9pZGYsIGZpbGwgPSBnY29kZSkpICsKICAgIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSAidGYtaWRmIikgKwogICAgZmFjZXRfd3JhcCh+Z2NvZGUsIG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV94X3Jlb3JkZXJlZCgpICsKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCmBgYAoKYGBge3J9CmxpYnJhcnkodGV4dGRhdGEpCmxpYnJhcnkocmVjaXBlcykKbGlicmFyeSh0aWR5bW9kZWxzKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0ZXh0cmVjaXBlcykKbGlicmFyeSh0aGVtaXMpCmxpYnJhcnkodHVuZSkKbGlicmFyeShnbG1uZXQpCmxpYnJhcnkocmFuZ2VyKQpgYGAKCgpgYGB7cn0KbWRhdGEgPC0gb2NwdDIgJT4lIHVuZ3JvdXAoKSAlPiUgIHNlbGVjdChnY29kZSx0ZXh0KQoKb2NwdDIgJT4lIHVuZ3JvdXAoKSAlPiUgIHNlbGVjdChnY29kZSx0ZXh0KSAlPiUgY291bnQoZ2NvZGUpCgojZ2xvdmU2YiA8LSBlbWJlZGRpbmdfZ2xvdmU2YihkaW1lbnNpb25zID0gMTAwKQoKc2V0LnNlZWQoMTIzNCkKCnJlbV9wdW5jdCA8LSByZWdleCgiW1s6cHVuY3Q6XV0iKQpyZW1fZGlnIDwtIHJlZ2V4KCJbWzpkaWdpdDpdXSIpCgptZGF0YSAlPD4lIG11dGF0ZSh0ZXh0PXN0cl9zcXVpc2godGV4dCksCiAgICAgICAgICAgICAgICAgIHRleHQ9c3RyX3JlbW92ZV9hbGwodGV4dCxyZW1fcHVuY3QpLAogICAgICAgICAgICAgICAgICB0ZXh0PXN0cl9yZW1vdmVfYWxsKHRleHQscmVtX2RpZykpCmBgYAoKCmBgYHtyfQptZGF0YSAlPiUgZ3JvdXBfYnkoZ2NvZGUpICU+JSBjb3VudChzb3J0ID0gVCkjICU+JSBzbGljZSgxOjgpICU+JSB1bmdyb3VwKCkgIyAlPiUgZ2dwbG90KGFlcyh4ID0gZ2NvZGUsIHkgPSBuKSkgKyBnZW9tX2NvbCgpCgptZGF0YSAlPD4lIGZpbHRlcihnY29kZSAlaW4lIGMoIjQwMSIsIjQwMyIsIjQwNCIsICI0MDciLCAiNDA1IiwiNDEzIiwiNDE0IiwiNDE3IiwiNDE2IiwiOTk5IikpCiMgbWRhdGEgJTw+JSBmaWx0ZXIoIWdjb2RlICVpbiUgYygiNDA5IiwiNDEwIiwiNDExIikpCiMgbWRhdGEgJTw+JSBkcm9wX25hKCkKbWRhdGEgJTw+JSBtdXRhdGUoZ2NvZGU9YXMuZmFjdG9yKGdjb2RlKSkKCiNkb3duc2FtcGxpbmcKCm1kYXRhICU+JSBmaWx0ZXIoZ2NvZGUgJWluJSBjKCI5OTkiKSkKCm5vX2xhYmVsX2luZGV4IDwtIHdoaWNoKG1kYXRhJGdjb2RlPT05OTkpCiMgbGFiZWxlZF9pbmRleCA8LSB3aGljaCghbWRhdGEkZ2NvZGU9PTk5OSkKcmFuZG9tX2luZGV4ZXMgPC0gc2FtcGxlKDE6bGVuZ3RoKG5vX2xhYmVsX2luZGV4KSwgbGVuZ3RoKG5vX2xhYmVsX2luZGV4KS0zMDAsIHJlcGxhY2U9RikKIyByYW5kb21fZG93bnNhbXBsZSA8LSBub19sYWJlbF9pbmRleFstYyhyYW5kb21faW5kZXhlcyldCgptZGF0YSA8LW1kYXRhWy1jKG5vX2xhYmVsX2luZGV4W2MocmFuZG9tX2luZGV4ZXMpXSksXQoKbWRhdGEgJT4lIGNvdW50KGdjb2RlKQpgYGAKCgpgYGB7cn0Kd3JpdGUuY3N2KG1kYXRhLCAibWRhdGFfMi5jc3YiKQpgYGAKCgpgYGB7cn0KdGlkeV9zcGxpdCA8LSBpbml0aWFsX3NwbGl0KG1kYXRhLCBzdHJhdGEgPSBnY29kZSwgcHJvcCA9IDAuNykKdHJhaW5fZGF0YSA8LSB0cmFpbmluZyh0aWR5X3NwbGl0KQp0ZXN0X2RhdGEgPC0gdGVzdGluZyh0aWR5X3NwbGl0KQp0aWR5X3NwbGl0CmBgYAoKCmBgYHtyfQp0cmFpbl9kYXRhIDwtIHJlY2lwZShnY29kZX4uLCBkYXRhID0gdHJhaW5fZGF0YSkgJT4lIHRoZW1pczo6c3RlcF91cHNhbXBsZShnY29kZSkgJT4lIHByZXAoKSAlPiUganVpY2UoKQoKCnRyYWluX2RhdGEgJTw+JSBtdXRhdGUodGV4dD1hcy5jaGFyYWN0ZXIodGV4dCkpCmBgYAoKCmBgYHtyfQpkYXRhX3JlcyA8LSB0cmFpbl9kYXRhICU+JSB2Zm9sZF9jdihzdHJhdGEgPSBnY29kZSwgdiA9IDEwLCByZXBlYXRzID0gMykKZGF0YV9yZXMgPC0gdmZvbGRfY3YodHJhaW5fZGF0YSkKYGBgCgoKYGBge3J9CnRmX2lkZl9yZWMgPC0gcmVjaXBlKGdjb2RlIH4gLiwgZGF0YSA9IHRyYWluX2RhdGEpICU+JQogIHN0ZXBfdG9rZW5pemUodGV4dCkgJT4lCiAgc3RlcF9zdGVtKHRleHQpICU+JQogIHN0ZXBfc3RvcHdvcmRzKHRleHQpICU+JQogIHN0ZXBfdG9rZW5maWx0ZXIodGV4dCwgbWF4X3Rva2VucyA9IDEwMDApICU+JQogIHN0ZXBfdGZpZGYoYWxsX3ByZWRpY3RvcnMoKSkKCnRmX2lkZl9kYXRhIDwtIHRmX2lkZl9yZWMgJT4lIHByZXAoKSAlPiUganVpY2UoKQpgYGAKCgpgYGB7cn0KaGFzaF9yZWMgPC0gcmVjaXBlKGdjb2Rlfi4sIGRhdGEgPSB0cmFpbl9kYXRhKSAlPiUKICBzdGVwX3Rva2VuaXplKHRleHQpICU+JQogIHN0ZXBfc3RlbSh0ZXh0KSAlPiUKICBzdGVwX3N0b3B3b3Jkcyh0ZXh0KSAlPiUKICBzdGVwX3Rva2VuZmlsdGVyKHRleHQsIG1heF90b2tlbnMgPSAxMDAwKSAlPiUKICBzdGVwX3RleHRoYXNoKHRleHQsIG51bV90ZXJtcyA9IDEwMCkKCmhhc2hfcmVjICU+JSBwcmVwKCkgJT4lIGp1aWNlKCkKCmBgYAoKCmBgYHtyfQoKCgptb2RlbF9sZyA8LSBtdWx0aW5vbV9yZWcoKSAlPiUKICBzZXRfYXJncyhwZW5hbHR5PXR1bmUoKSwgbWl4dHVyZT1OVUxMKSAlPiUgCiAgc2V0X2VuZ2luZSgiZ2xtbmV0IikgJT4lCiAgc2V0X21vZGUoImNsYXNzaWZpY2F0aW9uIikKCmNvcmVzIDwtIHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpCgptb2RlbF9yZiA8LSByYW5kX2ZvcmVzdCgpICU+JQogIHNldF9lbmdpbmUoInJhbmdlciIsIGltcG9ydGFuY2UgPSAiaW1wdXJpdHkiLCBudW0udGhyZWFkcyA9IGNvcmVzKSAlPiUKICBzZXRfbW9kZSgiY2xhc3NpZmljYXRpb24iKQoKYGBgCgoKCmBgYHtyfQpsb2dpc3RpY19ncmlkIDwtIGdyaWRfcmVndWxhcihwYXJhbWV0ZXJzKG1vZGVsX2xnKSwgbGV2ZWxzID0gMykKbW9kZWxfY29udHJvbCA8LSBjb250cm9sX2dyaWQoc2F2ZV9wcmVkID0gVFJVRSkKbW9kZWxfbWV0cmljcyA8LSBtZXRyaWNfc2V0KGFjY3VyYWN5LCByb2NfYXVjKQpgYGAKCgpgYGB7cn0KbGluZWFyX3RmX3JlcyA8LSB0dW5lX2dyaWQobW9kZWxfbGcsIHRmX2lkZl9yZWMsIGdyaWQgPSBsb2dpc3RpY19ncmlkLCBjb250cm9sID0gbW9kZWxfY29udHJvbCwgbWV0cmljcyA9IG1vZGVsX21ldHJpY3MsIHJlc2FtcGxlcyA9IGRhdGFfcmVzKQpsaW5lYXJfaGFzaF9yZXMgPC0gdHVuZV9ncmlkKG1vZGVsX2xnLCBoYXNoX3JlYywgZ3JpZCA9IGxvZ2lzdGljX2dyaWQsIGNvbnRyb2wgPSBtb2RlbF9jb250cm9sLCBtZXRyaWNzID0gbW9kZWxfbWV0cmljcywgcmVzYW1wbGVzID0gZGF0YV9yZXMpCgpgYGAKCgoKYGBge3J9CndvcmtmbG93X2dlbmVyYWxfdGYgPC0gd29ya2Zsb3coKSAlPiUgYWRkX3JlY2lwZSh0Zl9pZGZfcmVjKQp3b3JrZmxvd19sZ190ZiA8LSB3b3JrZmxvd19nZW5lcmFsX3RmICU+JSBhZGRfbW9kZWwobW9kZWxfbGcpCndvcmtmbG93X3JmX3RmIDwtIHdvcmtmbG93X2dlbmVyYWxfdGYgJT4lIGFkZF9tb2RlbChtb2RlbF9yZikKCndvcmtmbG93X2dlbmVyYWxfaGFzaCA8LSB3b3JrZmxvdygpICU+JSBhZGRfcmVjaXBlKGhhc2hfcmVjKQp3b3JrZmxvd19sZ19oYXNoIDwtIHdvcmtmbG93X2dlbmVyYWxfaGFzaCAlPiUgYWRkX21vZGVsKG1vZGVsX2xnKQp3b3JrZmxvd19yZl9oYXNoIDwtIHdvcmtmbG93X2dlbmVyYWxfaGFzaCAlPiUgYWRkX21vZGVsKG1vZGVsX3JmKQpgYGAKCgpgYGB7cn0KbGluZWFyX3RmX3JlcyAlPiUgYXV0b3Bsb3QoKQpiZXN0X3BhcmFtX2xpbmVhcl90Zl9yZXMgPC0gbGluZWFyX3RmX3JlcyAlPiUgc2VsZWN0X2Jlc3QobWV0cmljID0gJ2FjY3VyYWN5JykKYmVzdF9wYXJhbV9saW5lYXJfdGZfcmVzCndvcmtmbG93X2ZpbmFsX2xnX3RmIDwtIHdvcmtmbG93X2xnX3RmICU+JQogIGZpbmFsaXplX3dvcmtmbG93KHBhcmFtZXRlcnMgPSBiZXN0X3BhcmFtX2xpbmVhcl90Zl9yZXMpCgpsb2dfcmVzX3RmIDwtIHdvcmtmbG93X2ZpbmFsX2xnX3RmICU+JQogIGZpdF9yZXNhbXBsZXMocmVzYW1wbGVzID0gZGF0YV9yZXMsCiAgICAgICAgICAgICAgICBtZXRyaWNzID0gbWV0cmljX3NldChyZWNhbGwsIHByZWNpc2lvbiwgZl9tZWFzLCBhY2N1cmFjeSwga2FwLCByb2NfYXVjLCBzZW5zKSwgY29udHJvbCA9IGNvbnRyb2xfcmVzYW1wbGVzKHNhdmVfcHJlZCA9IFRSVUUpKQoKbG9nX3Jlc190ZiAlPiUgY29sbGVjdF9tZXRyaWNzKHN1bW1hcml6ZSA9IFRSVUUpCmBgYAoKCmBgYHtyfQpsaW5lYXJfaGFzaF9yZXMgJT4lIGF1dG9wbG90KCkKYmVzdF9wYXJhbV9saW5lYXJfaGFzaF9yZXMgPC0gbGluZWFyX2hhc2hfcmVzICU+JSBzZWxlY3RfYmVzdChtZXRyaWMgPSAnYWNjdXJhY3knKQpiZXN0X3BhcmFtX2xpbmVhcl9oYXNoX3JlcwoKd29ya2Zsb3dfZmluYWxfbGdfaGFzaCA8LSB3b3JrZmxvd19sZ19oYXNoICU+JQogIGZpbmFsaXplX3dvcmtmbG93KHBhcmFtZXRlcnMgPSBiZXN0X3BhcmFtX2xpbmVhcl9oYXNoX3JlcykKCmxvZ19yZXNfaGFzaCA8LSB3b3JrZmxvd19maW5hbF9sZ19oYXNoICU+JQogIGZpdF9yZXNhbXBsZXMoIHJlc2FtcGxlcyA9IGRhdGFfcmVzLAogICAgICAgICAgICAgICAgIG1ldHJpY3MgPSBtZXRyaWNfc2V0KHJlY2FsbCwgcHJlY2lzaW9uLCBmX21lYXMsIGFjY3VyYWN5LCBrYXAsIHJvY19hdWMsIHNlbnMpLCBjb250cm9sID0gY29udHJvbF9yZXNhbXBsZXMoc2F2ZV9wcmVkID0gVFJVRSkpCgpsb2dfcmVzX2hhc2ggJT4lIGNvbGxlY3RfbWV0cmljcyhzdW1tYXJpemUgPSBUUlVFKQpgYGAKCmBgYHtyfQoKcmZfcmVzX2hhc2ggPC0gd29ya2Zsb3dfcmZfaGFzaCAlPiUKICBmaXRfcmVzYW1wbGVzKHJlc2FtcGxlcyA9IGRhdGFfcmVzLAogICAgICAgICAgICAgICAgbWV0cmljcyA9IG1ldHJpY19zZXQocmVjYWxsLCBwcmVjaXNpb24sIGZfbWVhcywgYWNjdXJhY3ksIGthcCwgcm9jX2F1Yywgc2VucyksCiAgICAgICAgICAgICAgICBjb250cm9sID0gY29udHJvbF9yZXNhbXBsZXMoIHNhdmVfcHJlZCA9IFRSVUUpKQoKcmZfcmVzX2hhc2ggJT4lIGNvbGxlY3RfbWV0cmljcyhzdW1tYXJpemUgPSBUUlVFKQoKYGBgCgoKYGBge3J9CnJmX3Jlc190ZiA8LSB3b3JrZmxvd19yZl90ZiAlPiUKICBmaXRfcmVzYW1wbGVzKHJlc2FtcGxlcyA9IGRhdGFfcmVzLAogICAgICAgICAgICAgICAgbWV0cmljcyA9IG1ldHJpY19zZXQocmVjYWxsLCBwcmVjaXNpb24sIGZfbWVhcywgYWNjdXJhY3ksIGthcCwgcm9jX2F1Yywgc2VucyksCiAgICAgICAgICAgICAgICBjb250cm9sID0gY29udHJvbF9yZXNhbXBsZXMoIHNhdmVfcHJlZCA9IFRSVUUpKQpyZl9yZXNfdGYgJT4lIGNvbGxlY3RfbWV0cmljcyhzdW1tYXJpemUgPSBUUlVFKQoKYGBgCmBgYHtyfQpsb2dfbWV0cmljc190ZiA8LSBsb2dfcmVzX3RmICU+JSBjb2xsZWN0X21ldHJpY3Moc3VtbWFyaXNlID0gVFJVRSkgJT4lIG11dGF0ZShtb2RlbCA9ICJMb2dpc3RpYyBSZWdyZXNzaW9uIFRGLWlkZiIpCmxvZ19tZXRyaWNzX2hhc2ggPC0gbG9nX3Jlc19oYXNoICU+JSBjb2xsZWN0X21ldHJpY3Moc3VtbWFyaXNlID0gVFJVRSkgJT4lIG11dGF0ZShtb2RlbCA9ICJMb2dpc3RpYyBSZWdyZXNzaW9uIEhhc2giKQpyZl9tZXRyaWNzX3RmIDwtIHJmX3Jlc190ZiAlPiUgY29sbGVjdF9tZXRyaWNzKHN1bW1hcmlzZSA9IFRSVUUpICU+JSBtdXRhdGUobW9kZWwgPSAiUmFuZG9tIEZvcmVzdCBURi1pZGYiKQpyZl9tZXRyaWNzX2hhc2ggPC0gcmZfcmVzX2hhc2ggJT4lIGNvbGxlY3RfbWV0cmljcyhzdW1tYXJpc2UgPSBUUlVFKSAlPiUgbXV0YXRlKG1vZGVsID0gIlJhbmRvbSBGb3Jlc3QgSGFzaCIpCgoKbW9kZWxfY29tcGFyZSA8LSBiaW5kX3Jvd3MoCiAgbG9nX21ldHJpY3NfdGYsIAogIGxvZ19tZXRyaWNzX2hhc2gsIAogIHJmX21ldHJpY3NfdGYsIAogIHJmX21ldHJpY3NfaGFzaCkKCgoKcmZfc3RhdDEgPC0gcmZfcmVzX3RmICU+JSBjb2xsZWN0X21ldHJpY3Moc3VtbWFyaXplID0gVFJVRSkKcmZfc3RhdDEKYGBgCgoKYGBge3J9Cm1vZGVsX2NvbXAgPC0gbW9kZWxfY29tcGFyZSAlPiUKICBzZWxlY3QobW9kZWwsIC5tZXRyaWMsIG1lYW4sIHN0ZF9lcnIpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAubWV0cmljLCB2YWx1ZXNfZnJvbSA9IGMobWVhbiwgc3RkX2VycikpCgoKbW9kZWxfY29tcCAlPiUKICBhcnJhbmdlKG1lYW5fZl9tZWFzKSAlPiUKICAgIG11dGF0ZShtb2RlbCA9IGZjdF9yZW9yZGVyKG1vZGVsLCBtZWFuX2ZfbWVhcykpICU+JQogICAgICBnZ3Bsb3QoYWVzKG1vZGVsLCBtZWFuX2ZfbWVhcywgZmlsbD1tb2RlbCkpICsKICAgICAgZ2VvbV9jb2woKSArIGNvb3JkX2ZsaXAoKSArCiAgICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiWWxHbiIpICsKICAgICAgZ2VvbV90ZXh0KHNpemUgPSAzLCBhZXMobGFiZWwgPSByb3VuZChtZWFuX2ZfbWVhcywgMiksIHkgPSBtZWFuX2ZfbWVhcyArIDAuMDgpLCB2anVzdCA9IDEpCgpgYGAKCmBgYHtyfQpyZl9wcmVkX3RmIDwtIHJmX3Jlc190ZiAlPiUKICBjb2xsZWN0X3ByZWRpY3Rpb25zKCkKCnJmX3ByZWRfdGYgJT4lIGNvbmZfbWF0KGdjb2RlLCAucHJlZF9jbGFzcykKCnJmX3ByZWRfdGYgJT4lIGNvbmZfbWF0KGdjb2RlLCAucHJlZF9jbGFzcykgJT4lIGF1dG9wbG90KHR5cGUgPSAiaGVhdG1hcCIpCmBgYAoKYGBge3J9CgpsYXN0X2ZpdF9yZiA8LSBsYXN0X2ZpdCh3b3JrZmxvd19yZl90ZiwKICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgPSB0aWR5X3NwbGl0LAogICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWNzID0gbWV0cmljX3NldChyZWNhbGwsIHByZWNpc2lvbiwgZl9tZWFzLCBhY2N1cmFjeSwga2FwLCByb2NfYXVjLCBzZW5zKSkKCnJmX3N0YXQyIDwtIGxhc3RfZml0X3JmICU+JSBjb2xsZWN0X21ldHJpY3MoKQpyZl9zdGF0MgoKbGFzdF9maXRfcmYgJT4lIGNvbGxlY3RfcHJlZGljdGlvbnMoKSAlPiUgY29uZl9tYXQoZ2NvZGUsIC5wcmVkX2NsYXNzKSAlPiUgYXV0b3Bsb3QodHlwZSA9ICJoZWF0bWFwIikKCm15dCA8LSByZl9zdGF0MSAlPiUgbGVmdF9qb2luKHJmX3N0YXQyLCBieT0iLm1ldHJpYyIpICU+JSBzZWxlY3QoLm1ldHJpYywgbWVhbiwgc3RkX2VyciwgLmVzdGltYXRlKQpteXQKCmBgYAoKYGBge3J9CmxpYnJhcnkoc3RhcmdhemVyKQpsaWJyYXJ5KHh0YWJsZSkKI3N0YXJnYXplcihteXQsIHR5cGUgPSAibGF0ZXgiLCBvdXQgPSAibW9kZWxzLnRleCIpCnN0YXJnYXplcihteXQsIHR5cGUgPSAidGV4dCIpCnByaW50KHh0YWJsZShteXQsIHR5cGUgPSAibGF0ZXgiKSwgZmlsZSA9ICJteXQudGV4IikKCm55dCA8LSBvY3B0MiAlPiUgZ3JvdXBfYnkoZ2NvZGUpICU+JSBjb3VudCgpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KHBhcnNuaXApCmxpYnJhcnkocmVjaXBlcykKbGlicmFyeSh3b3JrZmxvd3MpCmxpYnJhcnkobW9kZWxkYXRhKQoKcHJvZF9kcyA8LSByZWFkLmNzdigibGlzdGVkX2RhbmlzaF9jb21wYW5pZXNfdGV4dF9wdXJlLmNzdiIpICU+JSBzZWxlY3QoLVgpCgp0Zl9pZGZfcmVjX3Byb2R1Y3Rpb24gPC0gcmVjaXBlKGdjb2RlIH4gLiwgZGF0YSA9IHByb2RfZHMpICU+JQogIHN0ZXBfdG9rZW5pemUodGV4dCkgJT4lCiAgc3RlcF9zdGVtKHRleHQpICU+JQogIHN0ZXBfc3RvcHdvcmRzKHRleHQpICU+JQogIHN0ZXBfdG9rZW5maWx0ZXIodGV4dCwgbWF4X3Rva2VucyA9IDEwMDApICU+JQogIHN0ZXBfdGZpZGYoYWxsX3ByZWRpY3RvcnMoKSkKCnRmX2lkZl9wcm9kIDwtIHRmX2lkZl9yZWNfcHJvZHVjdGlvbiAlPiUgcHJlcCgpICU+JSBqdWljZSgpCgptb2RlbF9yZiA8LSByYW5kX2ZvcmVzdCgpICU+JQogIHNldF9lbmdpbmUoInJhbmdlciIsIGltcG9ydGFuY2UgPSAiaW1wdXJpdHkiLCBudW0udGhyZWFkcyA9IHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpKSAlPiUKICBzZXRfbW9kZSgiY2xhc3NpZmljYXRpb24iKQoKd2ZfcmZfdGYgPC0gd29ya2Zsb3coKSAlPiUKICAgICAgICAgICAgYWRkX3JlY2lwZSh0Zl9pZGZfcmVjKSAlPiUKICAgICAgICAgICAgYWRkX21vZGVsKG1vZGVsX3JmKQoKCmBgYAoKCmBgYHtyfQoKYGBgCgoKYGBge3J9CmBgYAoKCg==